﻿using Microsoft.Extensions.DependencyInjection;
using System;
using System.Diagnostics;

namespace Athena.Performance.Client
{
    using Models;
    using Models.Arguments;
    using Options;
    using ProxyGenerator;
    using Transport.DotNetty;
    class Program
    {
        private static IServiceProvider BuildServiceCollection(Action<IServiceCollection> action)
        {
            var serviceCollection = new ServiceCollection();
            serviceCollection.AddLogging();
            action?.Invoke(serviceCollection);
            return serviceCollection.BuildServiceProvider();
        }

        static void Main(string[] args)
        {
            var clientProvider = BuildServiceCollection((serviceCollection) =>
            {
                serviceCollection.AddAthenaCore(new ServiceDescriptor()
                {
                    Id = "athena.xunit.client.test",
                    Name = "雅典娜RPC-client-Test"
                }, new AthenaOptions()
                {
                    RouteAddressOption = new RouteAddressOption()
                    {
                        FileServiceMultipleRouteDirectory = "C:\\athena\\routes"
                    }
                });
                serviceCollection.AddDefaultClientRuntime();
                serviceCollection.AddAthenaProxy();
                serviceCollection.AddDotNettyTransport();

            });
            var serviceProxyFactory = clientProvider.GetRequiredService<IServiceProxyFactory>();
            var user = serviceProxyFactory.CreateProxy<IUser>();
            var resultUserLogin = user.Login(new ArguUserLogin()
            {
                UserName = "Danny",
                Password = "123"
            }).GetAwaiter().GetResult();
            var stopWatch = new Stopwatch();
            if (!string.IsNullOrWhiteSpace(resultUserLogin.Token))
            {
                Console.WriteLine("预热成功,开始压力测试");
                stopWatch.Start();
                int success = 0;
                for (var i = 0; i < 1000; i++)
                {
                    var result = user.Login(new ArguUserLogin()
                    {
                        UserName = "Danny",
                        Password = "123"
                    }).GetAwaiter().GetResult();
                    if (!string.IsNullOrWhiteSpace(resultUserLogin.Token))
                    {
                        success++;
                    }
                }
                stopWatch.Stop();
                Console.WriteLine($"1000次压测结束,成功：{success},失败：{1000 - success},耗时：{stopWatch.ElapsedMilliseconds} ms");


                stopWatch.Reset();
                stopWatch.Start();
                success = 0;
                for (var i = 0; i < 10000; i++)
                {
                    var result = user.Login(new ArguUserLogin()
                    {
                        UserName = "Danny",
                        Password = "123"
                    }).GetAwaiter().GetResult();
                    if (!string.IsNullOrWhiteSpace(resultUserLogin.Token))
                    {
                        success++;
                    }
                }
                stopWatch.Stop();
                Console.WriteLine($"10000次压测结束,成功：{success},失败：{10000 - success},耗时：{stopWatch.ElapsedMilliseconds} ms");

                stopWatch.Reset();
                stopWatch.Start();
                success = 0;
                for (var i = 0; i < 100000; i++)
                {
                    var result = user.Login(new ArguUserLogin()
                    {
                        UserName = "Danny",
                        Password = "123"
                    }).GetAwaiter().GetResult();
                    if (!string.IsNullOrWhiteSpace(resultUserLogin.Token))
                    {
                        success++;
                    }
                }
                stopWatch.Stop();
                Console.WriteLine($"100000次压测结束,成功：{success},失败：{100000 - success},耗时：{stopWatch.ElapsedMilliseconds} ms");
            }
            else
            {
                Console.WriteLine("预热失败");
            }
            Console.WriteLine("压测结束");
            Console.ReadKey();
        }
    }
}
